package com.ruoyi.net.netconf.examples;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;

public class UdpTimerPollingWithTimeout {
    private static final int PORT = 7889;
    private static final String TARGET_IP = "10.20.1.44";
    private static final int BUFFER_SIZE = 1024;
    private static final long POLLING_INTERVAL = 5000; // 轮询间隔，单位：毫秒
    private static final int TIMEOUT = 2000; // 接收数据的超时时间，单位：毫秒
    // 序列号  25 40
    private static Byte sno = 0;

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    /**
     * Hex字符串转byte
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte
     */
    public static byte hexToByte(String inHex){
        return (byte)Integer.parseInt(inHex,16);
    }

    /**
     * hex字符串转byte数组
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte数组结果
     */
    public static byte[] hexToByteArray(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            //奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            //偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    public static void main(String[] args) {
        try {
            // 创建 DatagramSocket 并绑定源端口为 7889
            DatagramSocket socket = new DatagramSocket(PORT);
            socket.setSoTimeout(TIMEOUT);
            InetAddress targetAddress = InetAddress.getByName(TARGET_IP);
            // 启动定时任务
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    try {
                        // 要发送的数据
                        if (sno == Byte.MAX_VALUE) {
                            sno = Byte.MIN_VALUE;
                        } else {
                            sno = (byte) ((sno + 1) & 0xFF);
                        }

                        // 28 + 21
                        char[] bytes = {0x0, 0x0, 0x0, 0x4f, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x82, 0x46, 0x48, 0x4d, 0x50, 0x2, 0xe1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x4c,
                                0x0, 0x0, 0x0, 0x72,
                                0x4a, 0x43, 0x4, 0x21, 0x88, 0x0, 0x31, 0x0, 0x0, 0x81, 0x4c,
                                0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d,
                                0x80, 0x1, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

//                        String ori = "0000004a000100010000008246484d5002e1010100000047000000724a430421880031000081470000000000000000005d8001ffffff000000010009000000000001ffffffffffff000000420000000100000000ffff00000000000000010000002c0000000000000002000000020000000001010100000000000000000000040000000001010100000000000000";
//                        ori.length(); //142
                        ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
                        for (int i = 0; i < bytes.length; i++) {
                            if (i == 23 || i == 38) {
                                buffer.put(sno);
                            }
                            else {
                                buffer.put((byte) bytes[i]);
                            }
                        }
                        buffer.flip();
                        byte[] sendData = buffer.array();
                        // fos 28
                        // 协议头21字节
                        // 15字节
                        //byte[] sendData = cArrayStringToByteArray(cArrayString);
                        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, targetAddress, PORT);
                        socket.send(sendPacket);
                        System.out.println("数据已发送");

                        // 接收数据
                        byte[] receiveData = new byte[BUFFER_SIZE];
                        DatagramPacket receivePacket = new DatagramPacket(receiveData, BUFFER_SIZE);
                        try {
                            socket.receive(receivePacket);
                            System.out.println("接收到的数据长度: " + receivePacket.getLength());
                            // 处理接收到的数据
                            byte[] receivedBytes = receivePacket.getData();
                            for (int i = 0; i < receivePacket.getLength(); i++) {
                                System.out.print((char) receivedBytes[i]);
                            }
                        } catch (Exception e) {
                            System.out.println("接收数据超时或出现异常: " + e.getMessage());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, 0, POLLING_INTERVAL);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}